<?php

declare(strict_types=1);

namespace Tools\Command;

/**
 * Class Console
 *
 * @package Tools\Command
 */
class Console
{
    /** @var string */
    protected string $input;
    /** @var string */
    protected string $output;
    /** @var string */
    protected string $error;

    /** @var resource $inputStream */
    protected $inputStream;
    /** @var resource $outputStream */
    protected $outputStream;
    /** @var resource $errorStream */
    protected $errorStream;

    /**
     * Console constructor.
     *
     * @param string $input
     * @param string $output
     * @param string $error
     * @throws \Exception
     */
    public function __construct(string $input = 'php://stdin', string $output = 'php://stdout', string $error = 'php://stderr')
    {
        $this->input = $input;
        $this->output = $output;
        $this->error = $error;

        $this->initialize();
    }

    /**
     * Initialize.
     *
     * @throws \Exception
     */
    protected function initialize()
    {
        $this->inputStream = fopen($this->input, 'r');
        $this->outputStream = fopen($this->output, 'w');
        $this->errorStream = fopen($this->error, 'w');

        if (false === $this->inputStream || false === $this->outputStream || false === $this->errorStream) {
            throw new \Exception('Initialize failure!');
        }
    }

    /**
     * @return string
     */
    public function getInput(): string
    {
        return $this->input;
    }

    /**
     * @return string
     */
    public function getOutput(): string
    {
        return $this->output;
    }

    /**
     * @return string
     */
    public function getError(): string
    {
        return $this->error;
    }

    /**
     * Get input.
     *
     * @return string
     */
    public function input(): string
    {
        return trim(fgets($this->inputStream));
    }

    /**
     * Output content.
     *
     * @param string $content
     */
    public function output(string $content)
    {
        fputs($this->outputStream, $content);
    }

    /**
     * Write error.
     *
     * @param string $content
     */
    public function error(string $content)
    {
        fputs($this->errorStream, $content);
    }
}
